#pragma once
#include "ContourDot.h"
#include "Curve.h"
#include <list>

// Forward declarations
class Calculator;
class NeighborEnumerator;
namespace Gdiplus
{
	class Graphics;
	class Pen;
	class SolidBrush;
	class GraphicsPath;
	class RectF;
};


class Stroke
{
	typedef std::list<ContourDot> DotCollection;
	typedef std::list<ContourDot>::iterator DotIterator;
	typedef std::list<ContourDot>::const_iterator ConstDotIterator;
	friend class StrokeVertexesFinder;

	DotCollection mDots;
	bool mIsClosed;
	float mFrontEta, mBackEta;

	int mID;
	static int sNextID;

	// support of mouse tracking and drawing
	ConstDotIterator mNearestDot;
	RECT mBounds, mBoundsExtended;

	// support of serialization
	float mAverageLineWidth;
	float mAverageBrightness;
	Gdiplus::GraphicsPath* mPath;
public:
	enum PlaceConstant
	{
		kBeforeFront = -1,
		kAfterEnd = -2
	};

public:
	Stroke();
	Stroke(const Stroke&);
	~Stroke();
	//----------------
	bool Initialize(int x, int y, Calculator&); 
	int GetID() const;
	bool IsValid() const;
	bool IsClosed() const;
	void Finalize(Calculator&);

	int GetDotCount() const;

	void DrawCurve(Gdiplus::Graphics&, const Gdiplus::Pen*) const;
	void DrawDotCenters(Gdiplus::Graphics&, const Gdiplus::SolidBrush*,
		const Gdiplus::Pen*, float radius) const;
	void DrawDotRects(Gdiplus::Graphics&, const Gdiplus::Pen*) const;
	void DrawDotInnerShapes(Gdiplus::Graphics&, const Gdiplus::Pen*) const;
	void DrawDotSideColors(Gdiplus::Graphics&) const;

	bool FindNearestDot(float x, float y, float areaEnlargement, bool& outSelectedDotChanged);
	void UnselectNearestDot();
	void GetHighlightedInfo(std::wostringstream& output) const;

	const RECT& GetBounds(bool extended) const;
	bool IsIntersecting(const RECT&, bool useExtendedBounds) const;
	bool IsIntersecting(const Gdiplus::RectF&, bool useExtendedBounds) const;

	Curve CreateCurve(int place) const;
	void RegisterEndDots(NeighborEnumerator&) const;
	const ContourDot* GetContourDotAt(int place) const;
	float GetTerminatingEta(int place) const;

	// getting path information
	float AverageLineWidth() const;
	float AverageBrightness() const;
	const Gdiplus::GraphicsPath* GetPathPtr() const;

private:
	void InitializePath();
};

